iT邦幫忙

2022 iThome 鐵人賽

DAY 20
0
Modern Web

為期 N 天的 react 小冒險系列 第 20

用 react hook 寫一個簡易計算機吧-下-day20

  • 分享至 

  • xImage
  •  

昨天寫到鍵入數字部分,今天接續把 +-/*= 的運算處理完吧~

加減乘除

執行 dispatch({ type: "該按鈕的數值" });
但這邊有一點要注意,如果 state.calcProgress 最末位也是 +-*/ 任一個值,則新按下的 +-*/ 會取代掉最末位的 +-*/
總之不可以出現 2+3+67+- 兩個運算符號相連的情況
ex: 1+1+2+ 按下 - 會變成 1+1+2-

一樣在 Calculator.js 中寫

function keyOperator(currentStr, targetOpartorString) {
    let returnStr = "";
    let lastAlphabet = currentStr[currentStr.length - 1];
    let operatorRegex = /\+|\-|\*|\//g;
    if (lastAlphabet.match(operatorRegex) === null) {
      // 如果最後一位不為運算符號,則將按下的運算符號添加到 currentStr 尾端
      returnStr = { calcProgress: currentStr.concat(targetOpartorString) };
    } else {
      // 如果最後一位不為運算符號,則裁掉最後一位,並將按下的運算符號添加到 currentStr 尾端
      returnStr = {
        calcProgress: currentStr
          .slice(0, currentStr.length - 1)
          .concat(targetOpartorString)
      };
    }
    return returnStr;
  }
...
function reducer(state, action) {
    let lastAlphabet = state.calcProgress[state.calcProgress.length - 1];
    switch (action.type) {
      // if lastAlphabet is +-*/ next +-*/ will replace it
      case "+":
        return keyOperator(state.calcProgress, "+");
      case "-":
        return keyOperator(state.calcProgress, "-");
      case "*":
        return keyOperator(state.calcProgress, "*");
      case "/":
        return keyOperator(state.calcProgress, "/");
      case "=":
        return handleCalculate(state.calcProgress);
      case ".":
        // 不能出現 .. 這種情況,其他都可以
        if (lastAlphabet === ".") {
          return { calcProgress: state.calcProgress };
        } else {
          return { calcProgress: state.calcProgress + "." };
        }
      ...
      default:
        throw new Error("some error happened");
    }
  }
...

等於

這裡動用一個黑魔法XD eval()
將 state.calcProgress 整個字串轉為運算的算式
但既然稱之為黑魔法,就表示不能隨便亂用,只能偶爾為之(等鐵人賽處理完再做進一步的說明吧 先賣個關子

...
 function handleCalculate(currentStr) {
    let result = eval(currentStr).toString();
    return { calcProgress: result };
  }
...

這時候計算機就大功告成了~

經驗尚淺,寫的冗長&醜的部分還請各路大大指教啊XD
CodeSandBox 的部分在這裡

參考資料

https://stackoverflow.com/questions/13077923/how-can-i-convert-a-string-into-a-math-operator-in-javascript
string-concat
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/String/concat
string-slice
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/slice
https://regex101.com/


上一篇
用 react hook 寫一個簡易計算機吧-中-day19
下一篇
react route-1(基本設置/Routes/Route/Link)-day21
系列文
為期 N 天的 react 小冒險30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言